﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections.ObjectModel;
using System.Net.Mail;
using System.Net;
using System.Threading.Tasks;
using WHLRDF.Log;

namespace WHLRDF
{
    /// <summary>
    /// 接收方式
    /// </summary>
    public enum MailType
    {
        POP3,
        IMAP,
        SMTP
    }
    /// <summary>
    /// 邮件发送
    /// </summary>
    public class SmtpHelper
    {
        SmtpClient client;
        public AttachmentCollection Attachments;//附件集合
        public MailAddressCollection BCC = new MailAddressCollection();//密送
        public MailAddressCollection CC = new MailAddressCollection();//抄送
        public MailAddressCollection To = new MailAddressCollection();//接受人Id
        public SmtpHelper()
        {

            string server = ApplicationEnvironments.Site.SMTP.Server;
            int port = ApplicationEnvironments.Site.SMTP.Port;
            string userName = ApplicationEnvironments.Site.SMTP.Account;
            string pwd = ApplicationEnvironments.Site.SMTP.Password;
            InitEmail(server, port, userName, pwd);
        }

        private static SmtpHelper _smtpService;
        private static object _locker = new object();
        public static SmtpHelper SmtpService
        {
            get {
                lock (_locker)
                {
                    if (_smtpService == null)
                    {
                        _smtpService = new SmtpHelper();
                    }
                }
                return _smtpService;
            }
        }
        public SmtpHelper(string server,int port,string userName,string pwd)
        {
            InitEmail(server, port, userName, pwd);
        }
        
        private void InitEmail(string host, int port, string userName, string pwd)
        {
            client = new SmtpClient(host, port);
            client.Timeout = 10000;
            client.EnableSsl = true;
            client.UseDefaultCredentials = false;
            client.DeliveryMethod = SmtpDeliveryMethod.Network;
            client.Credentials = new NetworkCredential(userName, pwd);
        }
        
        public async Task<bool> SendEmailSync(string SendAddress,string subject,string body)
        {
            
            return  await Task.Run<bool>(() => {
                try
                {
                    SendEmail(SendAddress, subject, body);
                }
                catch (Exception ex)
                {
                    LogHelper.Error(ex,ex);
                    return false;
                }
              
                return true;
            });
           
           

        }
        public bool SendEmail(string SendAddress, string subject, string body)
        {
            MailMessage msg = new MailMessage();

            msg.From = msg.Sender = new MailAddress(SendAddress, ApplicationEnvironments.ApplicationName, Encoding.UTF8);

            msg.IsBodyHtml = true;
            msg.Subject = subject;
            msg.Body = string.Format(body);

            msg.BodyEncoding = Encoding.UTF8;
            if (Attachments != null && Attachments.Count > 0)
            {
                foreach (Attachment attach in Attachments)
                    msg.Attachments.Add(attach);
            }

            if (CC != null && CC.Count > 0)
            {
                foreach (MailAddress address in CC)
                    msg.CC.Add(address);
            }
            if (BCC != null && BCC.Count > 0)
            {
                foreach (MailAddress address in BCC)
                    msg.Bcc.Add(address);
            }
            if (To != null && To.Count > 0)
            {
                foreach (MailAddress address in To)
                    msg.To.Add(address);
            }
            else
                throw new Exception("请选择接收人地址");
            client.Send(msg);
            return true;


        }

        public Attachment GetAttachment(string fileName,string name)
        {
            if (name!="")
                return new Attachment(fileName, name);
            else
                return new Attachment(fileName);
            
        }

        public Attachment GetAttachment(Stream stream, string name)
        {
                return new Attachment(stream, name);
        }
        ///// <summary>
        ///// 接收邮件的方法
        /// </summary>
        /// <param name="type">收取方式</param>
        /// <param name="sysEmail">收取指定的邮件</param>
        /// <param name="IsDeleted">true表示收取后直接删除</param>
        /// <returns></returns>
        public List<object> Receive(MailType type, string sysEmail, bool IsDeleted)
        {
            //switch (type)
            //{
            //    case MailType.POP3:
            //        if (m_Port == 0)
            //            m_Port = 110;
            //        if (!this.POP3(entites, sysEmail, IsDeleted)) { return null; }
            //        break;
            //    case MailType.IMAP:
            //        if (m_Port == 0)
            //            m_Port = 143;
            //        if (!this.IMAP(entites)) { return null; }
            //        break;
            //}
            return null;
        }

        ///// <summary>
        ///// POP3接收方式
        ///// </summary>
        ///// <param name="entities">接收实体</param>
        ///// <param name="sysEmail">收取特定的邮箱(postmaster@haopoo.com)</param>
        ///// <param name="IsDeleted">true表示收取后删除，false表示删除</param>
        ///// <returns></returns>
        //private bool POP3(MailEntitis entities, string sysEmail, bool IsDeleted)
        //{
        //    try
        //    {
        //        Pop3Client client = new Pop3Client(m_Server, m_Port, m_user, m_password);
        //        client.Timeout = 6000;
        //        client.Connect(true);
        //        Pop3MessageInfoCollection collection = client.ListMessages(true);
        //        int i = 0;
        //        foreach (Pop3MessageInfo info in collection)
        //        {
        //            try
        //            {
        //                if (i >= m_maxMail)
        //                    continue;
        //                MailMessage mail = client.FetchMessage(info.SequenceNumber);
        //                MailEntity entity = new MailEntity();
        //                if (sysEmail != "" && (mail.From == null || mail.From.ToString().ToLower().IndexOf(sysEmail.ToLower()) == -1))
        //                {
        //                    if (IsDeleted)
        //                        client.DeleteMessage(info.SequenceNumber);
        //                    continue;
        //                }
        //                if (mail.IsBodyHtml)
        //                    entity.Body = mail.HtmlBody;
        //                else
        //                    entity.Body = mail.Body;
        //                entity.From = mail.From;
        //                entity.Sender = mail.Sender;
        //                entity.Cc = mail.CC;
        //                entity.Replyto = mail.ReplyTo;
        //                entity.SendDate = mail.Date;
        //                entity.Key = info.UniqueId;
        //                entity.Size = info.Size;
        //                entity.Subject = mail.Subject;
        //                entity.To = mail.To;
        //                entity.SequenceNumber = info.SequenceNumber;
        //                entities[mail.MessageId] = entity;
        //                i++;
        //                if (IsDeleted)
        //                    client.DeleteMessage(entity.SequenceNumber);
        //            }
        //            catch
        //            {
        //                continue;
        //            }
        //        }
        //        client.Disconnect();
        //    }
        //    catch (Exception ex)
        //    {
        //        throw ex;
        //    }
        //    return true;
        //}

        ///// <summary>
        ///// IMAP接收方式
        ///// </summary>
        ///// <param name="entities"></param>
        ///// <returns></returns>
        //private bool IMAP(MailEntitis entities)
        //{
        //    try
        //    {
        //        ImapClient client = new ImapClient(m_Server, m_Port, m_user, m_password);
        //        client.Timeout = 3000;
        //        client.Connect(true);

        //        ImapFolderInfoCollection Imapfolders = client.ListFolders();
        //        foreach (ImapFolderInfo ImapFolder in Imapfolders)
        //        {
        //            while (true)
        //            {
        //                string UniqueId = ImapFolder.GetNextUniqueId();
        //                if (UniqueId == null || UniqueId == "")
        //                    break;
        //                MailMessage mail = client.FetchMessage(UniqueId);
        //                MailEntity entity = new MailEntity();
        //                if (mail.IsBodyHtml)
        //                    entity.Body = mail.HtmlBody;
        //                else
        //                    entity.Body = mail.Body;
        //                entity.From = mail.From;
        //                entity.Sender = mail.Sender;
        //                entity.Cc = mail.CC;
        //                entity.Replyto = mail.ReplyTo;
        //                entity.SendDate = mail.Date;
        //                entity.Key = mail.MessageId;
        //                entity.Subject = mail.Subject;
        //                entities[mail.MessageId] = entity;
        //                break;
        //            }
        //        }
        //        //// ImapMessageInfoCollection collection = client.ListMessages();
        //        // foreach (ImapMessageInfo info in collection)
        //        // {

        //        // }
        //        client.Disconnect();
        //    }
        //    catch (Exception ex)
        //    {
        //        return false;
        //    }
        //    return true;
        //}

        public async Task<bool> SendSync( string toaddress, string subject, string body)
        {
            return await SendSync(ApplicationEnvironments.Site.SMTP.SendAddress, toaddress, subject, body);
        }

        /// <summary>
        /// 异步发送邮件
        /// </summary>
        /// <param name="sendAddress"></param>
        /// <param name="subject"></param>
        /// <param name="body"></param>
        /// <returns></returns>
        public async Task<bool> SendSync(string sendAddress,string toaddress,string subject,string body)
        {
            this.To.Add(toaddress);
            return await this.SendEmailSync(sendAddress,subject,body);
        }


        /// <summary>
        /// 同步发送邮件
        /// </summary>
        /// <param name="sendAddress"></param>
        /// <param name="toaddress"></param>
        /// <param name="subject"></param>
        /// <param name="body"></param>
        /// <param name="strError"></param>
        /// <returns></returns>
        public bool Send(string sendAddress, string toaddress, string subject, string body,ref string strError)
        {
            if (string.IsNullOrWhiteSpace(toaddress))
            {
                strError = "邮箱不存在，无法发送";
                return false;
            }
            if (string.IsNullOrWhiteSpace(subject))
            {
                strError = "邮箱标题不能为空";
                return false;
            }
            if (string.IsNullOrWhiteSpace(subject))
            {
                strError = "邮箱内容不能为空";
                return false;
            }
            var arrToAddress = toaddress.Split(new char[] { ',', ';' });
            
            foreach (var address in arrToAddress)
            {
                if (!string.IsNullOrWhiteSpace(address))
                {
                    this.To.Add(address);
                }
            }
            return this.SendEmail(sendAddress, subject, body);
        }
    }
}
